/**
 * 
 */
package jpb;

import java.io.File;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * Interface describing a concrete JVM implementation and version. More
 * specifically, it represents a JVM capable of executing in a command-line
 * environment.
 *
 * <p>
 * From the <a href=
 * "http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19042"
 * >JVM specification $2.17.1</a>:<br>
 * 'The Java virtual machine starts execution by invoking the method main of some
 * specified class and passing it a single argument, which is an array of
 * strings. This causes the specified class to be loaded (§2.17.2), linked
 * (§2.17.3) to other types that it uses, and initialized (§2.17.4). The method
 * main must be declared <tt>public</tt>, <tt>static</tt>, and <tt>void</tt>.
 *
 * <p> 
 * The manner in which the initial class is specified to the Java virtual
 * machine is beyond the scope of this specification, but it is typical, in host
 * environments that use command lines, for the fully qualified name of the
 * class to be specified as a command-line argument and for subsequent
 * command-line arguments to be used as strings to be provided as the argument
 * to the method main. (...)'
 *
 * <p>
 * Therefore, a JVM implementation does not need to support start-up as a
 * command-line environment process, but this interface is designed to support
 * only such types of JVM.
 * 
 * <p>
 * This interface provides a {@link StartupCommandSelector} instance tied to the
 * represented JVM that is responsible for providing clients (notably the
 * {@link JavaProcessBuilder}) with the default JVM startup command in a given
 * environment.
 *
 * <p>
 * JVM implementation also provides a set of {@link JvmArg} instances representing common JVM arguments standardized
 * by the Java Language Specification across all compatible JVMs. Finally, concrete implementations should provide
 * custom JVM arg types by means of static singleton fields.
 *
 * @see jpb.JvmArg
 * @see jpb.hotspot.HotspotJvm
 * @author Dariusz Kordonski
 */
public interface Jvm {


    /**
     * The main Java command used to spawn the JVM process.
     * 
     * @return name of the command in the host system that starts the JVM.
     */
    StartupCommandSelector commandSelector();

    /**
     * <p>
     * Verifies that this startup command is valid in the current context by running a probe process.
     *
     * <p>
     * <b>WARN:</b> this will attempt to run a probe Java process to verify that the command is valid in the current
     * context.
     *
     * @param startupCommand command to verify
     * @return <code>true</code>, if the command is a valid Java command, <code>false</code> otherwise
     */
    boolean dryRun(CommandArg startupCommand);

    /**
     * <p>
     * An entry point to a Java application may be:
     * <ul>
     * <li>a class implementing public static method named 'main',
     * <li>a Java archive (JAR) containing such a class, whose name is referred
     * to in a 'manifest.mf' file, in the META-INF directory of the JAR.
     * </ul>
     *
     * <p>
     * For one Java application startup only one of those options may be used.
     *
     * <p>
     * This method provides {@link JvmArg} instance to evaluate and convert entry points into command line
     * arguments. For unknown entry point implementations are free to raise {@link InvalidJvmArgException}.
     * 
     * @return command line argument representing entry point into the JVM
     */
    JvmArg<EntryPoint> entryPointArg();
    
    
    /**
     * <p>
     * Provide {@link JvmArg} class path argument for given list of file objects, each
     * representing a single class-path entry.
     *
     * @return class path JVM argument
     */
    JvmArg<List<File>> classPathArg();


    /**
     * Provide a max-memory command line argument. The max-memory argument specifies maximum amount of memory that
     * the JVM will claim from the operating system. This has direct influence
     * on the maximum size of the JVM's heap.
     *
     * <p>
     * As specified by the <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#15730"
     * >JVM specification $3.5.3</a> a JVM 'may provide the programmer or the
     * user control over the initial size of the heap, as well as, if the heap
     * can be dynamically expanded or contracted, control over the maximum and
     * minimum heap size'.
     *
     * @return {@link jpb.JvmArg} representing this JVM's min-memory argument
     */
    JvmArg<MemArg> maxMemoryArg();

    /**
     * Provide min-memory command line argument for validating and converting {@link MemArg}
     * instances. The min-memory argument specifies the amount of memory that the
     * JVM will occupy from the operating system at startup.
     *
     * <p>
     * As specified by the <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#15730"
     * >JVM specification $3.5.3</a> a JVM 'may provide the programmer or the
     * user control over the initial size of the heap, as well as, if the heap
     * can be dynamically expanded or contracted, control over the maximum and
     * minimum heap size'.
     *
     * @return {@link jpb.JvmArg} representing this JVM's min-memory argument
     */
    JvmArg<MemArg> minMemoryArg();

    /**
     * Provide a max-stack-size command line argument that will validate and convert any given
     * argument expressed in terms of {@link MemArg}. This argument specifies the maximum amount
     * of memory that may be allocated to a single JVM stack.
     *
     * <p>
     * As specified by the <a href=
     * "http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6654"
     * >JVM specification $3.5.2</a>: '(...) specification permits
     * Java virtual machine stacks either to be of a fixed size or to
     * dynamically expand and contract as required by the computation. If the
     * Java virtual machine stacks are of a fixed size, the size of each Java
     * virtual machine stack may be chosen independently when that stack is
     * created. A Java virtual machine implementation may provide the programmer
     * or the user control over the initial size of Java virtual machine stacks,
     * as well as, in the case of dynamically expanding or contracting Java
     * virtual machine stacks, control over the maximum and minimum sizes.'
     *
     * @return {@link jpb.JvmArg} representing this JVM's max-stack-size argument type
     */
    JvmArg<MemArg> maxStackSizeArg();

    
    /**
     * Provide {@link JvmArg} for handling system properties of the new Java process.
     * 
     * @return system properties command line argument
     */
    JvmArg<Map<String,String>> systemPropertiesArg();

}
